import fs from "fs-extra";
import fg from "fast-glob";
import { BaseTask, TaskResult } from "../../common/tasks/BastTask.js";
import { SVNSumary, SVNOperationTask } from "../../common/tasks/SVNOperationTask.js";
import { toolchain } from "../../toolchain.js";
import path from "path";

export declare type ICheckNewApkResult = {
    needNewApk?: false
} | {
    needNewApk: true
    hitPrefab: string
    hitCS: string
}

/**
 * unity android检查是否需要换包
 */
export class AndroidCheckNewApkTask extends BaseTask<ICheckNewApkResult> {
    async run(): Promise<TaskResult<ICheckNewApkResult>> {
        let data: ICheckNewApkResult = {};
        
        let newCSCacheContent = '';
        const csInfos: { cs: string, guid: string }[] = [];
        // 获取所有cs脚本
        const csRoot = path.join(toolchain.params.workSpacePath, 'Assets');
        const css = await fg('**/*.cs', { cwd: csRoot });
        for (const cs of css) {
            if (cs.includes('Editor')) continue;
            const guid = await toolchain.unity.readGUID(path.join(csRoot, cs + '.meta'));
            csInfos.push({cs, guid});
            newCSCacheContent += `${guid}, ${cs}\n`;
        }

        const nguids: { cs: string, guid: string }[] = [];
        const csCache = path.join(toolchain.params.workSpacePath, `../.build/csCache.txt`);
        if (fs.existsSync(csCache)) {
            // 存在csCache文件的话，比对上次构包用到的脚本
            const cache = await fs.readFile(csCache, 'utf-8');
            for (const csi of csInfos) {
                if (!cache.includes(csi.guid)) {
                    nguids.push(csi);
                }
            }
        } else {
            // 不存在csCache的话，通过svn记录获取
            const svnRst = toolchain.taskHelper.getResult<SVNSumary>(SVNOperationTask.name);
            if (svnRst != null) {
                const ncss = svnRst.data?.addNewCsharps;
                if (ncss?.length) {                    
                    for (const ncs of ncss) {
                        const guid = await toolchain.unity.readGUID(ncs + '.meta');
                        nguids.push({ cs: ncs, guid });
                    }
                }
            }
        }
        console.log(`${nguids.length} new cs files`);
        if (toolchain.option.buildExe) {
            await fs.ensureDir(path.dirname(csCache));
            await fs.writeFile(csCache, newCSCacheContent, 'utf-8');
        }

        if (nguids.length > 0) {
            const root = path.join(toolchain.params.workSpacePath, 'Assets/AssetSources');
            const prefabs = await fg('**/*.prefab', { cwd: root });
            for (const prefab of prefabs) {
                const content = await fs.readFile(path.join(root, prefab), 'utf-8');
                for (const ng of nguids) {
                    if (content.includes(ng.guid)) {
                        data = {
                            needNewApk: true,
                            hitPrefab: path.basename(prefab, '.prefab'),
                            hitCS: path.basename(ng.cs, '.cs')
                        }
                        break;
                    }
                }
                if (data.needNewApk) break;
            }
        }

        return { success: true, errorCode: 0, data };
    }
}
